package com.cincc.cinccimdemo.ui.conversation;

import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.cincc.cinccimdemo.MyApplication;
import com.cincc.cinccimdemo.R;
import com.cincc.cinccimdemo.adapter.ConversationAdapter;
import com.cincc.cinccimdemo.common.AttrConstants;
import com.cincc.cinccimdemo.common.Constants;
import com.cincc.cinccimdemo.common.MyUtils;
import com.cincc.cinccimdemo.common.TranslationUtils;
import com.cincc.cinccimdemo.common.callback.OnConversationRefreshListener;
import com.cincc.cinccimdemo.common.callback.OnGetMoreDataListener;
import com.cincc.cinccimdemo.model.CardInfo;
import com.cincc.cinccimdemo.model.ConversationInfo;
import com.cincc.cinccimdemo.model.MessageInfo;
import com.cincc.cinccimdemo.model.MessageInfoUI;
import com.cincc.cinccimdemo.model.OperationEntity;
import com.cincc.cinccimdemo.ui.IMBaseActivity;
import com.cincc.cinccimdemo.ui.conversation.detail.GroupDetailActivity;
import com.cincc.cinccimdemo.ui.conversation.detail.SingleDetailActivity;
import com.cincc.cinccimdemo.viewmodel.ConversationViewModel;
import com.cincc.cinccimdemo.viewmodel.GlobalViewModel;
import com.cincc.cinccimdemo.widget.ConversationInputLayout;
import com.cincc.cinccimdemo.widget.ConversationMoreLayout;
import com.cincc.cinccimdemo.widget.VoiceArcView;
import com.cincc.im.callback.ImCallback;
import com.cincc.im.core.IMSipPhoneCtrl;
import com.cincc.im.core.SipCoreUtils;
import com.cincc.im.listener.ImRcvFriendNotifyListener;
import com.cincc.im.listener.ImRcvGroupNotifyListener;
import com.cincc.im.listener.ImRcvMsgListener;
import com.cincc.im.listener.ImRcvMsgNotifyListener;
import com.cincc.im.model.ImMessageInfo;
import com.cincc.im.model.ImResponse;
import com.cincc.im.model.dbmodel.GroupMessageInfo;
import com.cincc.im.model.dbmodel.P2PMessageInfo;
import com.cincc.im.model.dbmodel.SequenceInfo;
import com.cincc.im.model.enums.ImSendType;
import com.cincc.im.model.enums.SendStatus;
import com.cincc.im.model.notify.FriendNotify;
import com.cincc.im.model.notify.group.GroupNotify;
import com.cincc.im.model.notify.msg.GroupMsgNotify;
import com.cincc.im.model.notify.msg.MsgNotify;
import com.cincc.im.model.notify.msg.P2PMsgNotify;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class ConversationActivity extends IMBaseActivity implements ImRcvMsgListener, ImRcvFriendNotifyListener, ImRcvGroupNotifyListener, ImRcvMsgNotifyListener, OnConversationRefreshListener {
    private static final String TAG = "ConversationActivity";
    ConversationInfo conversationInfo = new ConversationInfo();
    private ConversationAdapter conversationAdapter;
    private VoiceArcView voiceArcView;
    private ConversationMoreLayout conversationMoreLayout;
    private ConversationInputLayout conversationInputLayout;
    SwipeRefreshLayout swipeRefreshLayout;
    RecyclerView recyclerView;
    List<MessageInfoUI> list = new ArrayList<>();

    TranslationUtils translationUtils;

    public ConversationViewModel conversationViewModel;
    public GlobalViewModel sequenceViewModel;

    @Override
    protected int contentLayout() {
        return R.layout.activity_conversation;
    }


    @Override
    protected void bindViews() {
        super.bindViews();

        conversationInfo.targetId = getIntent().getStringExtra(AttrConstants.TARGET_ID);
        conversationInfo.targetName = getIntent().getStringExtra(AttrConstants.TARGET_NAME);
        conversationInfo.imSendType = ImSendType.fromValue(getIntent().getIntExtra(AttrConstants.CHAT_TYPE, 0));
        conversationInfo.draft = getIntent().getStringExtra(AttrConstants.DRAFT);

        setTitle(conversationInfo.targetName);

        swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
        recyclerView = findViewById(R.id.recyclerView);

        voiceArcView = findViewById(R.id.voiceArcView);
        translationUtils = findViewById(R.id.translationUtils);
        conversationMoreLayout = findViewById(R.id.chat_more);
        conversationInputLayout = findViewById(R.id.chat_input);
        conversationMoreLayout.setEditText(conversationInputLayout.getExitText());
    }

    @Override
    protected void bindEvents() {
        super.bindEvents();
        SipCoreUtils.getInstance().addImRcvFriendNotifyListener(this);
        SipCoreUtils.getInstance().addImRcvMsgListener(this);
        SipCoreUtils.getInstance().addImRcvGroupNotifyListener(this);
        SipCoreUtils.getInstance().addImRcvMsgNotifyListener(this);
        MyUtils.addOnConversationRefreshListener(this);
        recyclerView.setOnTouchListener((v, event) -> {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                conversationInputLayout.clickRecycler();
            }
            return false;
        });
        // 控制打开键盘的时候列表自动顶上去
        recyclerView.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
            if (oldBottom > bottom) {
                if (list.isEmpty()) return;
                recyclerView.post(() -> recyclerView.scrollToPosition(list.size() - 1));
            }
        });
        //去掉点击默认动画，否则刷新单条数据的时候会闪烁
        ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
        swipeRefreshLayout.setOnRefreshListener(() -> {
            swipeRefreshLayout.setRefreshing(false);
//            conversationViewModel.loadMoreLiveData(conversationInfo).observe(this, new Observer<List<MessageInfoUI>>() {
//                @Override
//                public void onChanged(List<MessageInfoUI> messageInfoUIS) {
//                    runOnUiThread(() -> conversationAdapter.loadMoreData(messageInfoUIS));
//                }
//            });
            conversationViewModel.getMoreData(conversationInfo, new OnGetMoreDataListener() {
                @Override
                public void onCallback(List<MessageInfoUI> list) {
                    runOnUiThread(() -> {
                        conversationAdapter.loadMoreData(list);
                    });
                }
            });
        });
    }

    @Override
    protected void afterViews() {
        super.afterViews();
        conversationViewModel = new ViewModelProvider(this).get(ConversationViewModel.class);
        conversationAdapter = new ConversationAdapter(this, list);
        conversationViewModel.conversationListLiveData(conversationInfo).observe(this, messageEntities -> {
            conversationAdapter.setConversations(messageEntities);
            recyclerView.scrollToPosition(conversationAdapter.getItemCount() - 1);
        });

        conversationViewModel.conversationLiveData().observe(this, messageRequest -> {
            conversationAdapter.addNewConversation(messageRequest);
            recyclerView.scrollToPosition(conversationAdapter.getItemCount() - 1);
        });
        conversationViewModel.updateConversationLiveData().observe(this, message -> conversationAdapter.updateConversation(message));
        conversationViewModel.operationLiveData().observe(this, this::doOperation);
        conversationViewModel.recallLiveData().observe(this, s -> conversationAdapter.recall(s));
        conversationViewModel.deleteLiveData().observe(this, s -> conversationAdapter.delete(s));
        MyApplication app = (MyApplication) getApplication();
        sequenceViewModel = app.getViewModel();
        sequenceViewModel.getSequenceLiveData().observe(this, this::sendSequence);
        sequenceViewModel.getCardLiveData().observe(this, this::sendCard);
        recyclerView.setAdapter(conversationAdapter);
        conversationAdapter.setConversationModel(conversationViewModel);
        conversationMoreLayout.setConversationModel(conversationViewModel, conversationInfo);
        conversationInputLayout.setParams(conversationViewModel, translationUtils, voiceArcView, conversationMoreLayout, conversationInfo);
        clearUnread();
    }

    private void clearUnread() {
        IMSipPhoneCtrl.getInstance().clearUnreadNum(conversationInfo.imSendType, conversationInfo.targetId);
        MyUtils.fireConversationListRefreshEvent();
    }

    @Override
    protected int menu() {
        return R.menu.conversation;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.menu_conversation_info) {
            showConversationInfo();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    //打开会话详情
    private void showConversationInfo() {
        Intent intent;
        if (ImSendType.isP2P(conversationInfo.imSendType)) {
            intent = new Intent(this, SingleDetailActivity.class);
        } else {
            intent = new Intent(this, GroupDetailActivity.class);
        }
        intent.putExtra("conversationInfo", conversationInfo);
        startActivity(intent);
    }

    public static void startSingleConversation(Context context, String targetId, String targetName) {
        Intent i = new Intent(context, ConversationActivity.class);
        i.putExtra(AttrConstants.CHAT_TYPE, ImSendType.IM_SINGLE_MESSAGE.value());
        i.putExtra(AttrConstants.TARGET_ID, targetId);
        i.putExtra(AttrConstants.TARGET_NAME, targetName);
        context.startActivity(i);
    }

    public static void startGroupConversation(Context context, String targetId, String targetName) {
        Intent i = new Intent(context, ConversationActivity.class);
        i.putExtra(AttrConstants.CHAT_TYPE, ImSendType.IM_GROUP_MESSAGE.value());
        i.putExtra(AttrConstants.TARGET_ID, targetId);
        i.putExtra(AttrConstants.TARGET_NAME, targetName);
        context.startActivity(i);
    }

    public static void startConversation(Context context, com.cincc.im.model.dbmodel.ConversationInfo conversationInfo) {
        Intent i = new Intent(context, ConversationActivity.class);
        i.putExtra(AttrConstants.CHAT_TYPE, conversationInfo.type.value());
        i.putExtra(AttrConstants.TARGET_ID, conversationInfo.targetId);
        i.putExtra(AttrConstants.TARGET_NAME, ImSendType.isP2P(conversationInfo.type) ? conversationInfo.userName : conversationInfo.groupName);
        i.putExtra(AttrConstants.DRAFT, conversationInfo.draft);
        context.startActivity(i);
    }

    private void doOperation(OperationEntity entity) {
        int operationId = entity.getOperationId();
        MessageInfoUI uiMessage = entity.getUiMessage();
        if (operationId == Constants.OPERATION_COPY) {
            try {
                JSONObject j = new JSONObject(uiMessage.getMessageInfo().messageContent);
                MyUtils.copyToClipboard(this, j.getString("msgContent"));
                Toast.makeText(this, "复制成功", Toast.LENGTH_SHORT).show();
            } catch (Exception e) {

            }
        } else if (operationId == Constants.OPERATION_RECALL) {
            IMSipPhoneCtrl.getInstance().withdraw(uiMessage.getRemoteMsgId(), imResponse -> {
                Log.e(TAG, "doOperation: " + imResponse.getCode());
            });
        } else if (operationId == Constants.OPERATION_DELETE) {
            String targetId = ImSendType.isP2P(uiMessage.getMessageInfo().imSendType) ? conversationInfo.targetId : uiMessage.getMessageInfo().groupId;
            IMSipPhoneCtrl.getInstance().deleteSingleHistory(uiMessage.getMessageInfo().imSendType, targetId, uiMessage.getRemoteMsgId());
            conversationViewModel.deleteLiveData().postValue(uiMessage.getRemoteMsgId());
        } else if (operationId == Constants.OPERATION_COLLECT) {
            IMSipPhoneCtrl.getInstance().addCollect(uiMessage.getRemoteMsgId(), new ImCallback() {
                @Override
                public void callback(ImResponse imResponse) {
                    String result = imResponse.getCode() == 0 ? "收藏成功" : imResponse.getMsg();
                    runOnUiThread(() -> Toast.makeText(ConversationActivity.this, result, Toast.LENGTH_SHORT).show());
                }
            });
        } else if (operationId == Constants.OPERATION_FORWARD) {

        } else if (operationId == Constants.OPERATION_QUOTE) {
            conversationInputLayout.quoteMessage(uiMessage);
        }
    }

    public void sendSequence(SequenceInfo sequenceInfo) {
        MessageInfo textMessage = MyUtils.getSequenceMessageInfo(sequenceInfo, conversationInfo.imSendType);
        MessageInfoUI uiMessage = new MessageInfoUI(textMessage);
        conversationViewModel.conversationLiveData().postValue(uiMessage);

        IMSipPhoneCtrl.getInstance().sendGroupSequence(sequenceInfo.fromGroupId, sequenceInfo.sequenceContent, sequenceInfo.sequenceId, sequenceInfo.fromUserId,
                sequenceInfo.fromUserName, sequenceInfo.participants, sequenceInfo.remark, new ImCallback() {
                    @Override
                    public void callback(ImResponse imResponse) {
                        if (imResponse.getCode() == 0) {
                            ImMessageInfo imMessageInfo = (ImMessageInfo) imResponse.getData();
                            uiMessage.setRemoteMsgId(imMessageInfo.msgId);
                        }
                        uiMessage.setMessageStatus(imResponse.getCode() == 0 ? SendStatus.SEND_SUCCESS : SendStatus.SEND_FAILED);
                        conversationViewModel.updateConversationLiveData().postValue(uiMessage);
                    }
                });
    }

    public void sendCard(CardInfo cardInfo) {
        String staffId = "11111";
        String profile = "22222";
        String theme = "0";
        String additionalParam = "2";
        MessageInfo textMessage = MyUtils.getCardMessageInfo(cardInfo, staffId, profile, theme, conversationInfo.imSendType);
        MessageInfoUI uiMessage = new MessageInfoUI(textMessage);
        conversationViewModel.conversationLiveData().postValue(uiMessage);

        IMSipPhoneCtrl.getInstance().sendCard(conversationInfo.imSendType, conversationInfo.targetId,
                staffId, cardInfo.friendInfoUI.nickName, cardInfo.friendInfoUI.protraitUrl,
                cardInfo.friendInfoUI.department, profile, cardInfo.ticket, theme, additionalParam, new ImCallback() {
                    @Override
                    public void callback(ImResponse imResponse) {
                        Log.e(TAG, "callback: " + imResponse.getCode() + "," + imResponse.getData());
                    }
                });
    }

    @Override
    protected void onPause() {
        super.onPause();
        MyUtils.setConversationDraft();
    }

    @Override
    public void onReceiveFriendNotify(FriendNotify message) {

    }

    @Override
    public void onReceiveGroupNotify(GroupNotify message) {

    }

    @Override
    public void onReceiveP2PMsg(P2PMessageInfo message) {
        if (conversationInfo.imSendType == ImSendType.IM_SINGLE_MESSAGE && conversationInfo.targetId.equals(message.targetId)) {
            MessageInfo messageInfo = MyUtils.getMessageInfo(message, conversationInfo.imSendType);
            conversationViewModel.conversationLiveData().postValue(new MessageInfoUI(messageInfo));
        }
    }

    @Override
    public void onReceiveGroupMsg(GroupMessageInfo message) {
        if (conversationInfo.imSendType == ImSendType.IM_GROUP_MESSAGE && conversationInfo.targetId.equals(message.groupId)) {
            MessageInfo messageInfo = MyUtils.getMessageInfo(message, conversationInfo.imSendType);
            conversationViewModel.conversationLiveData().postValue(new MessageInfoUI(messageInfo));
        }
    }

    @Override
    public void onReceiveMsgNotify(MsgNotify message) {
        if (message instanceof P2PMsgNotify && ImSendType.isP2P(conversationInfo.imSendType)) {
            String userId = ((P2PMsgNotify) message).userId;
            if (userId.equals(conversationInfo.targetId)) {
                runOnUiThread(() -> conversationViewModel.recallLiveData().postValue(message.messageId));
            }
        }
        if (message instanceof GroupMsgNotify && !ImSendType.isP2P(conversationInfo.imSendType)) {
            String groupId = ((GroupMsgNotify) message).groupId;
            if (groupId.equals(conversationInfo.targetId)) {
                runOnUiThread(() -> conversationViewModel.recallLiveData().postValue(message.messageId));
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        SipCoreUtils.getInstance().removeImMsgListener(this);
        SipCoreUtils.getInstance().removeImRcvFriendNotifyListener(this);
        SipCoreUtils.getInstance().removeImRcvGroupNotifyListener(this);
        SipCoreUtils.getInstance().removeImRcvMsgNotifyListener(this);
        MyUtils.removeOnConversationRefreshListener(this);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        conversationMoreLayout.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        conversationMoreLayout.onActivityResult(requestCode, resultCode, data);
        conversationInputLayout.onActivityResult(requestCode, resultCode, data);
    }


    @Override
    public void refreshConversation() {
        conversationViewModel.clearHistory();
    }
}
